package telas.componentes;

import javax.swing.JPanel;
import java.awt.Dimension;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.FocusManager;
import business.sistema.ExceptionSistema;
import business.sistema.IObjetoSistema;
import business.sistema.Observer;
import business.sistema.Subject;

public class CampoPopupLocalizador extends JPanel implements Subject, Observer
{
	private static final long serialVersionUID = 1L;
	private CampoTexto txtPesquisa = null;
	private Botao btnPesquisa = null;
	private IObjetoSistema objetoSelecionado = null;
	private String campoChavePesquisa = "";  
	private ArrayList<String[]> formatoGridPesquisa;  //  @jve:decl-index=0:
	private String descricaoPesquisa = "";
	private String classePesquisa = "";
	private String atributoVisualizacao = "";
	private String filtro = "";
	private String atributoObservado = "";
	private ArrayList<Observer> observers = null;

	/**
	 * 
	 */
	public CampoPopupLocalizador()
	{
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 */
	private void initialize() 
	{
        this.setLayout(new BoxLayout(this, javax.swing.BoxLayout.X_AXIS));
        this.setSize(new Dimension(143, 25));
        this.setPreferredSize(new java.awt.Dimension(207, 27));

        this.add(getTxtPesquisa(), null);
        this.add(getBtnPesquisa(), null);
	}

	/**
	 * This method initializes txtPesquisa	
	 * 	
	 * @return javax.swing.JTextField	
	 */
	private CampoTexto getTxtPesquisa() 
	{
		if (txtPesquisa == null) 
		{
			txtPesquisa = new CampoTexto();
			txtPesquisa.setEnabled(false);
		}
		
		return txtPesquisa;
	}

	/**
	 * This method initializes btnPesquisa	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private Botao getBtnPesquisa()
	{
		if (btnPesquisa == null) 
		{
			btnPesquisa = new Botao();
			btnPesquisa.setText("...");
			
			btnPesquisa.addActionListener
			(
				new java.awt.event.ActionListener() 
				{
					public void actionPerformed(java.awt.event.ActionEvent e) 
					{
						try
						{
							new Localizador(getObjeto(), 
											getCampoPesquisa(), 
											getFormatoGridPesquisa(), 
											getDescricaoPesquisa(),
											getCampo(),
											getFiltro());
							preencherCampoTexto();
							
							// Notifica os observadores sobre as mudan�as.
							notifyObservers();
							
							// Passa o foco para outro componente.
							FocusManager.getCurrentManager().focusNextComponent();
//							getParent().getParent().getParent().getParent()
							FocusManager.getCurrentManager().focusNextComponent();
						}
						catch(Exception ex)
						{
							new ExceptionSistema(ex);
						}
					}
				}
			);
		}
		return btnPesquisa;
	}

	/**
	 * Método responsável por obter objeto selecionado
	 * 
	 * @return objetoSelecionado : IObjetoSistema
	 */
	public IObjetoSistema getObjeto() throws Exception
	{
		if(objetoSelecionado == null)// || (objetoSelecionado.getClass() != Class.forName(classePesquisa)) )
		{
			Class<?> classe;

			classe = Class.forName(classePesquisa);
			objetoSelecionado = (IObjetoSistema)classe.newInstance();

		}
		
		return objetoSelecionado;
	}
	
	public void mudarInstanciaObjeto() throws Exception
	{
		Class<?> classe = Class.forName(classePesquisa);

		objetoSelecionado = (IObjetoSistema)classe.newInstance();
	}
	
	public void setObjeto(IObjetoSistema objeto) throws Exception
	{
		this.objetoSelecionado = objeto;
		preencherCampoTexto();
		notifyObservers();
	}

	public String getCampoPesquisa() 
	{
		return campoChavePesquisa;
	}
	
	private void preencherCampoTexto() throws Exception
	{
		Method objMetodo = null;
		try
		{
			if(getObjeto() != null)
			{
				Object objDados = getObjeto();
				Class<?> objClasse = objDados.getClass();
				
				objMetodo = objClasse.getMethod("get" + getAtributoVisualizacao());
				txtPesquisa.setText((String)objMetodo.invoke(objDados));
			}
			else
				getTxtPesquisa().setText("");
		}
		catch(NoSuchMethodException nsme)
		{
			throw nsme;
		}
		catch(InvocationTargetException ite)
		{
			throw ite;
		}
		catch(IllegalAccessException iae)
		{
			throw iae;
		}
	}

	public ArrayList<String[]> getFormatoGridPesquisa() 
	{
		return formatoGridPesquisa;
	}

	public String getDescricaoPesquisa() 
	{
		return descricaoPesquisa;
	}
	
	private CampoPopupLocalizador getCampo()
	{
		return this;
	}
	
	public void limpar() throws Exception
	{
		setObjeto(null);
	}

	public void setCampoPesquisa(String campoPesquisa)
	{
		this.campoChavePesquisa = campoPesquisa;
	}

	public void setFormatoGridPesquisa(ArrayList<String[]> formatoGridPesquisa)
	{
		this.formatoGridPesquisa = formatoGridPesquisa;
	}

	public void setDescricaoPesquisa(String descricaoPesquisa) 
	{
		this.descricaoPesquisa = descricaoPesquisa;
	}

	public String getAtributoVisualizacao() 
	{
		return atributoVisualizacao;
	}

	public void setAtributoVisualizacao(String atributoVisualizacao) 
	{
		this.atributoVisualizacao = atributoVisualizacao;
	}

	public String getClassePesquisa() 
	{
		return classePesquisa;
	}

	public void setClassePesquisa(String classePesquisa) 
	{
		this.classePesquisa = classePesquisa;
	}

	public void notifyObservers()
	{
		for(Observer observer : getObservers())
		{
			try
			{
				observer.update(getObjeto(), "");
			}
			catch(Exception ex)
			{
				new ExceptionSistema(ex);
			}
		}
	}

	public void registerObserver(Observer observer) 
	{
		getObservers().add(observer);
	}

	public void removeObserver(Observer observer) 
	{
		getObservers().remove(observer);
	}

	public ArrayList<Observer> getObservers() 
	{
		if(observers == null)
		{
			observers = new ArrayList<Observer>();
		}
		
		return observers;
	}

	public String getFiltro() 
	{
		return filtro;
	}

	public void setFiltro(String filtro) 
	{
		this.filtro = filtro;
	}

	@Override
	public void update(IObjetoSistema objeto, String mensagem) throws Exception 
	{
		if(!getAtributoObservado().equals(""))
		{
			Class<?> clsObjeto = objeto.getClass();
			Method objMetodo = clsObjeto.getMethod("get" + getAtributoObservado());

			IObjetoSistema objetoSelecionado = (IObjetoSistema)objMetodo.invoke(objeto); 

			setObjeto(objetoSelecionado);
		}
		else
		{
			setObjeto(objeto);
		}
	}

	public String getAtributoObservado() 
	{
		return atributoObservado;
	}

	public void setAtributoObservado(String atributoObservado) 
	{
		this.atributoObservado = atributoObservado;
	}
	
	public void setEnabled(boolean enabled)
	{
		getBtnPesquisa().setEnabled(enabled);
		super.setEnabled(enabled);
	}
}
